﻿//防止头文件被多次..
#ifndef DEFINE_H_INCLUDED
#define DEFINE_H_INCLUDED

//记得要放在头文件前面才管用
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <windows.h>
#include <time.h>
#include <math.h>
#include <io.h>

#define gap 500//全局间隔时间
#define MAXid 999999999//id的最大值
#define Pro_NAME "学生成绩信息管理系统" //程序名字
#define REPASS "123456" //重置密码默认值
#define MAXSCORE 150

//用户类型有三种 超级管理员1 班主任2 学生3
//链表头也有三种 0是老师信息 1是学生信息 2是学生成绩
//所有编号最大为9位数,第一位不为0
//一些简单的容错性
//为了尽量减少vs的警告向其妥协很多

typedef struct administrator
{
	char password[24];//长度不超23
	char connectinfo[40];//长度不超39
} administrator;

typedef struct tea_info
{
	int teaid;
	char name[24];//长度不超23
	int classid;
	char connectinfo[40];//长度不超39
	char password[24];//长度不超23
	struct tea_info* pre;
	struct tea_info* next;
} tea_info;

typedef struct stu_info
{
	int stuid;
	int classid;
	char name[24];//长度不超23
	int enroll_time;
	char connectinfo[40];//长度不超39
	char password[24];//长度不超23
	struct stu_info* pre;
	struct stu_info* next;
} stu_info;

typedef struct stu_score
{
	int stuid;
	int testid;
	int score[4];//语0 数1 英2
	struct stu_score* pre;
	struct stu_score* next;
} stu_score;

//变量
char pass_set[93];//92个允许的密码字符

int tea_num;
int stu_num;
int score_num;

int current_usertype;//用户类型有三种 超级管理员1 班主任2 学生3
int current_userid;

//链表均为单项链表
//链表头head 链表尾tail
//0是老师信息 1是学生信息 2是学生成绩
void* head[4];
void* tail[4];

administrator admin;

//函数

//返回值0退出系统，1退出账户重新登陆
int menu_admin();

//返回值0退出系统，1退出账户重新登陆
int menu_teacher();

//返回值0退出系统，1退出账户重新登陆
int menu_student();

//下面没有排序

//重置密码，非交互，传入的密码是正确的，直接放进结构体就可以了 成功返回1 失败返回0
int reset_pass(int type, int unique_id, char* newpass);

//输入密码，半交互，对密码进行合法性，过长过短检测，password长度为22，输入密码的函数，1成功
int input_pass(char* inputpass);

//自己修改自己密码，交互，包括输入密码，比对密码等，没成功就回退，传入参数确保存在，成功返回1 失败返回0
int change_pass(int type, int unique_id);

//输入姓名，半交互，名字长度检测，确保传回合法
int input_name(char* input);

//检查数字输入的合法性，半交互，用在选项和id和成绩，且能确定范围 成功返回真实值 失败返回0
int check_num(int a, int b);

//输入联系方式 半交互
int input_connectinfo(char* input);

//修改信息，交互 成功返回1，未修改成功返回0
int change_info(int type, int unique_id);

//报错用，半交互，无返回 直接退出程序 显示错误地方
void errorr(char* reason);

//查找tea_info结构体的指针 非交互 返回指针
tea_info* findteaid(int unique_id);

//查找stu_info结构体的指针 非交互 返回指针
stu_info* findstuid(int unique_id);

//多行打印班主任信息 非交互
void printteainfo(tea_info* p);

//多行打印学生信息 非交互
void printstuinfo(stu_info* p);

//保存信息回文件，非交互 不free掉内存，因为可能只是临时存储到文件中，最后程序关闭时系统会自动回收内存
int savetofile();

//打印某个学生成绩，非交互，确保传入id存在，会返回一共有几个成绩
int printstuscore(int unique_id);

//添加某学生成绩 交互 传入的id确定存在 要判断考试编号是否存在  增加返回1，没加返回0
int add_score(int unique_id);

//删除成绩 非交互 指定学号及考试相对顺序删除或者删除学号的所有考试 test_id 写-1
int del_score(int unique_id, int relative_sequential);

//删除学生 非交互 已确定id存在
int del_stu(int unique_id);

//初始化函数 非交互 成功返回1 失败返回0
int initialize();

//欢迎界面 非交互 成功返回1 失败返回0
void welcome();

//删除所有信息(除管理员) 非交互 成功返回1 失败返回0
int del_all();

//登录 交互 选择用户类型 登录 成功返回1 失败返回0
int login();

//导出信息到文件 非交互 0是老师信息，1是学生信息，2是学生成绩
int out_all_info(int type);

//添加学生 交互 成功添加返回1
int add_stu();

//增加老师 交互
int add_tea();

//删除老师 非交互 id确保存在
int del_tea(int unique_id);

//打印指定班级学生信息 非交互，指定班级id
int printclassstuinfo(int classid);

//打印指定班级学生成绩 非交互，指定班级id和考试编号
int printclassstuscore(int classid, int testid);

//找到老师的id 非交互 ，传入学生班级id，在链表中查找老师的id，
tea_info* findclassidtoteaid(int classid);

//所有人成绩排序 非交互 不用参数，返回成功1失败0
int sortstuscore();

#endif